using System.Collections.Generic;
using System.Linq;
using Map.MapObject.Building;
using MoonFramework.Scripts.Event;
using MoonFramework.Scripts.Mono;
using MoonFramework.Template;
using Tool.Name;
using UnityEngine;
using UnityEngine.EventSystems;

namespace Tool
{
    public class InputManager : BaseGameMono<InputManager>
    {
        private readonly List<RaycastResult> _raycastResults = new();
        [SerializeField] private LayerMask _mouseMapObjectLayer; //鼠标可交互地图对象层
        [SerializeField] private LayerMask _groundLayer;    //地面层
        [SerializeField] private LayerMask _bigMapObjectLayer;
        [SerializeField] private LayerMask _buildLayer; //建筑物层
        
        public Camera MainCamera { get; private set; } //主相机 
        private EventSystem _eventSystem;
        private bool _isBuild;
        
        public void Init()
        {
            MainCamera = Camera.main;   
            _eventSystem = EventSystem.current;
            MonoManager.Instance.SendUpdateEvent(OnUpdate);
        }
        
        /// <summary>
        ///  设置是否在建造状态
        /// </summary>
        /// <param name="isBuild">Is build.</param>
        public void SetIsBuild(bool isBuild) => _isBuild = isBuild;

        private void OnUpdate()
        {
            if(!_isBuild)
                CheckSelectMapObject();
        }
        

        /// <summary>
        ///     检查选中地图物体
        /// </summary>
        private void CheckSelectMapObject()
        {
            bool mouseButtonDown = Input.GetMouseButtonDown(0);
            bool mouseButton = Input.GetMouseButton(0);
            
            if (mouseButton || mouseButtonDown)
            {
                //如果检测到UI则无视
                if (CheckMouseOnUI()) return;
                //射线检测地图上的3D物体
                var ray = MainCamera.ScreenPointToRay(Input.mousePosition);
                if (Physics.Raycast(ray, out var hitInfo, 100, _mouseMapObjectLayer))
                    //回调Player的Attack方法
                    EventCenter.Instance.Callback(EventName.RayCast, hitInfo);
            }
        }

        /// <summary>
        ///     检查鼠标是否在ui上
        /// </summary>
        public bool CheckMouseOnUI()
        {
            var arg1 = new PointerEventData(_eventSystem)
            {
                position = Input.mousePosition
            };
            //射线检测
            EventSystem.current.RaycastAll(arg1, _raycastResults);
            if (_raycastResults.Any(raycast =>
                    raycast.gameObject.GetComponent<RectTransform>() && raycast.gameObject.name != "Mask"))
            {
                _raycastResults.Clear();
                return true;
            }

            _raycastResults.Clear();
            return false;
        }

        /// <summary>
        /// 获取鼠标在地面的世界坐标
        /// </summary>
        public bool GetMouseWorldPositionOnGround(Vector3 mousePos, out Vector3 worldPos)
        {
            if (Physics.Raycast(MainCamera.ScreenPointToRay(mousePos), out RaycastHit hitInfo,1000, _groundLayer))
            {
                worldPos = hitInfo.point;
                return true;
            }
            worldPos = Vector3.zero;
            return false;
        }

        /// <summary>
        /// 检测鼠标是否在较大地图对象上
        /// </summary>
        public bool CheckMouseOnBigMapObject()
        {
            return Physics.Raycast(MainCamera.ScreenPointToRay(Input.mousePosition), 1000, _bigMapObjectLayer);
        }

        /// <summary>
        /// 检查当格子停止拖拽时，是否在建筑物上 
        /// </summary>
        public bool CheckSlotEndOnBuilding(int itemID)
        {
            var ray = MainCamera.ScreenPointToRay(Input.mousePosition);
            if (!Physics.Raycast(ray, out var hitInfo, 100, _buildLayer)) return false;
            BaseBuilding building = hitInfo.collider.GetComponent<BaseBuilding>();
            return building.OnSlotEndDragSelect(itemID);
        }
    }
}